﻿using System.Net;
using System.Net.Sockets;
using UnityEngine;
using LiteNetLib;
using LiteNetLib.Utils;
using FrameOperateSync;
using System;

public class NetworkClient : MonoBehaviour, INetEventListener,ISyncNetwork
{
    private NetManager _netClient;

    private NetDataWriter _dataWriter;
    private NetPeer _ourPeer;

    public bool delaySimulateFlag { get; set; } = false;
    public int networkDelay { get; set; } = 0;
    public Action<int,KeyFramePackage[]> RecvedHander { get; set; }

    private bool startSyncFlag = false;

    public void StartNetwork()
    {
        _netClient = new NetManager(this);
        _dataWriter = new NetDataWriter();

        startSyncFlag = true;
        _netClient.UnconnectedMessagesEnabled = true;
        _netClient.UpdateTime = 15;
        _netClient.Start();


        var teskPck = new KeyFramePackage()
        {
            frameIndex = 1002, opDataCount = 1, playerSyncDates = new[]
            {
                new FrameOperateData()
                {
                    PlayerId = 101, LogicCode = 1001, Data = "{\"angleValue\":90}"
                }
            }
        };
        var str = JsonUtility.ToJson(teskPck);
        var newPck = JsonUtility.FromJson<KeyFramePackage>(str);
        Debug.Log($"ddddd info  = {teskPck.frameIndex.Equals(newPck.frameIndex)},{teskPck.opDataCount.Equals(newPck.opDataCount)},{teskPck.playerSyncDates[0].Data.Equals(newPck.playerSyncDates[0].Data)}");
    }

    [SerializeField]
    private bool connectFlag = false;
    void Update()
    {
        if (connectFlag)
        {
            connectFlag = false;
            var ip = IPAddress.Parse("192.168.1.107");
            var endpoint = new IPEndPoint(ip,6666);
           // _netClient
             var pper = _netClient.Connect(endpoint,"sample_app");
             
            //peer.
           Debug.Log("uuuuu +"+endpoint.Serialize().Size);  
//           var dw =  NetDataWriter.FromString("sample_app");
//           var bffff = dw.CopyData();
//           for (int i = 0; i < bffff.Length; i++)
//           {
//               Debug.LogError("show - "+bffff[i]);
//           }
            // _netClient.SendBroadcast(new byte[]{1}, 30000);
//            var x = BitConverter.ToInt32( new byte[] {5, 12, 0, 0}, 0);
//            var buff = System.Text.Encoding.UTF8.GetBytes("sample_app");
//            Debug.LogError($"test == {x}, {buff.Length}");
        }

        if (!startSyncFlag)
            return;

        var peer = _netClient.FirstPeer;
        if (peer != null && peer.ConnectionState == ConnectionState.Connected)
        {
            ////Fixed delta set to 0.05
            //var pos = _clientBallInterpolated.transform.position;
            //pos.x = Mathf.Lerp(_oldBallPosX, _newBallPosX, _lerpTime);
            //_clientBallInterpolated.transform.position = pos;

            ////Basic lerp
            //_lerpTime += Time.deltaTime / Time.fixedDeltaTime;
        }
        else
        {
            Debug.Log("寻找服务器");
            _netClient.SendBroadcast(new byte[] { 1 }, 5000);
        }
    }
    void FixedUpdate()
    {
        if (!startSyncFlag)
            return;
        _netClient.PollEvents();
    }

    void OnDestroy()
    {
        if (_netClient != null)
            _netClient.Stop();
    }

    public void OnPeerConnected(NetPeer peer)
    {
        Debug.Log("[CLIENT] We connected to " + peer.EndPoint);
        _ourPeer = peer;
    }

    public void OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode)
    {
        Debug.Log("[CLIENT] We received error " + socketErrorCode);
    }

    public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
    {
        if (messageType == UnconnectedMessageType.BasicMessage && _netClient.ConnectedPeersCount == 0 && reader.GetInt() == 1)
        {
            //Debug.Log("[CLIENT] Received discovery response. Connecting to: " + remoteEndPoint);
            _netClient.Connect(remoteEndPoint, "sample_app");
        }
    }

    public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
    {

    }

    public void OnConnectionRequest(ConnectionRequest request)
    {

    }

    public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
    {
        Debug.Log("[CLIENT] We disconnected because " + disconnectInfo.Reason);
    }

    public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod)
    {
        var ch = reader.GetChar();
        switch(ch)
        {
            case 'U':
                Debug.Log("连接建立成功");
                // NetworkUtility.MarkPlayerReady();
                //_successCalback?.Invoke();
                break;
            case 'C':
                Debug.Log("服务器返回C");
                _successCalback?.Invoke();
                break;
            case 'D':
                var index = reader.GetInt();
                var count = reader.GetInt();
                var str = reader.GetString();

                Debug.Log("reccccc str = "+ str);
                
                var sss = str.Split('#');
                KeyFramePackage[] packages = new KeyFramePackage[sss.Length];
                for(int i = 0;i<sss.Length;i++)
                {
                    packages[i] = JsonUtility.FromJson<KeyFramePackage>(sss[i]);
                }
                RecvedHander?.Invoke(index, packages);
                break;
            default: break;
        }
        reader.Clear();
    }

    public void SentPackage(KeyFramePackage netObj)
    {
        if (_dataWriter == null)
        {
            Debug.LogError("sync data error ... ");
            return;
        }
        var json = JsonUtility.ToJson(netObj);
        _dataWriter.Reset();
        _dataWriter.Put('D');
        _dataWriter.Put(json);
        
        Debug.LogError("send == "+json);
        
        _netClient.ConnectedPeerList[0].Send(_dataWriter, DeliveryMethod.Sequenced);
    }

    public void WaitServerBegin (Action successCallback)
    {
        if (_dataWriter == null)
        {
            Debug.LogError("sync data error ... ");
            return;
        }

        StartCoroutine(delayConnect());

        Debug.Log("buhuiab");
        _successCalback = successCallback;
    }

    System.Collections.IEnumerator delayConnect()
    {
        yield return new WaitForSeconds(5f);
        _dataWriter.Reset();
        _dataWriter.Put('C');
        _netClient.ConnectedPeerList[0].Send(_dataWriter, DeliveryMethod.Sequenced);
    }

    private Action _successCalback = null;
    private bool readyMsgFlag = false;
}

